<template>
  <div class="scene-wrapper">
    <button class="collapse-btn" @click="toggleCollapse" :title="isCollapsed ? '展开' : '收起'">
      <span class="btn-icon">{{ isCollapsed ? '⤢' : '⛶' }}</span>
    </button>
    <div class="scene-container" ref="container"></div>
    <div class="legend">
      <div class="legend-item" v-for="item in legendItems" :key="item.label">
        <span class="dot" :style="{ background: item.color }"></span>
        <span>{{ item.label }}</span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { computed, onBeforeUnmount, onMounted, reactive, ref } from 'vue'
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'

const props = defineProps({
  collapsed: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits(['toggle-collapse'])

const isCollapsed = computed(() => props.collapsed)

const container = ref(null)
let renderer
let scene
let camera
let controls
let animationId

const legendItems = reactive([
  { label: 'B04车间', color: 'linear-gradient(90deg, #00d4ff, #0088ff)' },
  { label: 'C07车间', color: 'linear-gradient(90deg, #4fc3f7, #2196f3)' },
  { label: '堆放场', color: 'linear-gradient(90deg, #81c784, #4caf50)' }
])

const toggleCollapse = () => {
  emit('toggle-collapse')
}

const createBlock = (width, height, depth, color) => {
  const geometry = new THREE.BoxGeometry(width, height, depth)
  const material = new THREE.MeshStandardMaterial({
    color,
    roughness: 0.3,
    metalness: 0.2,
    emissive: new THREE.Color(color).multiplyScalar(0.25)
  })
  return new THREE.Mesh(geometry, material)
}

const initScene = () => {
  const width = container.value.clientWidth
  const height = container.value.clientHeight

  renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
  renderer.setPixelRatio(window.devicePixelRatio)
  renderer.setSize(width, height)
  renderer.shadowMap.enabled = true
  container.value.appendChild(renderer.domElement)

  scene = new THREE.Scene()
  scene.fog = new THREE.FogExp2(0x0a1a2e, 0.015)

  camera = new THREE.PerspectiveCamera(38, width / height, 1, 1000)
  camera.position.set(0, 100, 90)

  controls = new OrbitControls(camera, renderer.domElement)
  controls.enableDamping = true
  controls.enablePan = false
  controls.maxPolarAngle = Math.PI / 2.05
  controls.minDistance = 80
  controls.maxDistance = 180

  const ambientLight = new THREE.AmbientLight(0x4a9eff, 0.6)
  scene.add(ambientLight)

  const dirLight = new THREE.DirectionalLight(0x6bb6ff, 0.8)
  dirLight.position.set(60, 120, 40)
  dirLight.castShadow = true
  scene.add(dirLight)

  const plane = new THREE.Mesh(
    new THREE.PlaneGeometry(260, 180),
    new THREE.MeshStandardMaterial({
      color: 0x043054,
      metalness: 0.3,
      roughness: 0.8,
      transparent: true,
      opacity: 0.9
    })
  )
  plane.rotation.x = -Math.PI / 2
  plane.receiveShadow = true
  scene.add(plane)

  // B04车间 - 位于左上区域
  const blockB04 = createBlock(80, 25, 50, 0x00d4ff)
  blockB04.position.set(-50, 12.5, -20)
  blockB04.castShadow = true
  scene.add(blockB04)

  // 堆放场 - 位于底部中央区域，在B04右侧
  const blockStorage = createBlock(60, 20, 35, 0x4caf50)
  blockStorage.position.set(0, 10, 20)
  blockStorage.castShadow = true
  scene.add(blockStorage)

  // C07车间 - 位于底部右侧区域，在堆放场右侧，确保不重合
  // 堆放场X范围：-30到30，C07宽度70(半宽35)，C07中心设为67确保有间隙
  const blockC07 = createBlock(70, 24, 40, 0x2196f3)
  blockC07.position.set(67, 12, 20)
  blockC07.castShadow = true
  scene.add(blockC07)

  const gridHelper = new THREE.GridHelper(260, 26, 0x0b4b7f, 0x0b4b7f)
  scene.add(gridHelper)

  const animate = () => {
    controls.update()
    renderer.render(scene, camera)
    animationId = requestAnimationFrame(animate)
  }

  animate()
}

const onResize = () => {
  if (!container.value || !renderer) return
  const width = container.value.clientWidth
  const height = container.value.clientHeight
  camera.aspect = width / height
  camera.updateProjectionMatrix()
  renderer.setSize(width, height)
}

onMounted(() => {
  initScene()
  window.addEventListener('resize', onResize)
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', onResize)
  cancelAnimationFrame(animationId)
  controls?.dispose()
  renderer?.dispose()
  container.value?.replaceChildren()
})
</script>

<style scoped>
.scene-wrapper {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 12px;
  border: 1px solid rgba(0, 235, 255, 0.25);
  background: rgba(3, 27, 52, 0.65);
  overflow: hidden;
  box-shadow: inset 0 0 50px rgba(0, 170, 255, 0.08);
}

.collapse-btn {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 40px;
  height: 40px;
  border: none;
  border-radius: 8px;
  background: linear-gradient(135deg, rgba(82, 224, 255, 0.25), rgba(41, 171, 255, 0.25));
  border: 1px solid rgba(82, 224, 255, 0.4);
  color: #52e0ff;
  font-size: 18px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
  transition: all 0.3s ease;
  backdrop-filter: blur(4px);
  box-shadow: 
    0 4px 12px rgba(0, 0, 0, 0.3),
    0 0 0 1px rgba(82, 224, 255, 0.2),
    inset 0 1px 0 rgba(255, 255, 255, 0.1);
}

.collapse-btn:hover {
  background: linear-gradient(135deg, rgba(82, 224, 255, 0.35), rgba(41, 171, 255, 0.35));
  border-color: rgba(82, 224, 255, 0.6);
  transform: scale(1.05);
  box-shadow: 
    0 6px 16px rgba(0, 0, 0, 0.4),
    0 0 0 1px rgba(82, 224, 255, 0.3),
    0 0 20px rgba(82, 224, 255, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.15);
}

.collapse-btn:active {
  transform: scale(0.95);
}

.btn-icon {
  display: block;
  line-height: 1;
  transition: transform 0.3s ease;
}

.scene-container {
  width: 100%;
  height: 100%;
}

.legend {
  position: absolute;
  bottom: 12px;
  left: 16px;
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  font-size: 12px;
  color: #a7dfff;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(5, 91, 139, 0.45);
  border: 1px solid rgba(0, 174, 255, 0.3);
}

.dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: linear-gradient(90deg, #2afcff, #007bff);
  box-shadow: 0 0 8px rgba(0, 217, 255, 0.6);
}
</style>

